package models

import (
	"github.com/astaxie/beego/orm"
	"reflect"
	"time"
)

type BaseModels struct {
	CreateTime string `json:"create_time"`
	UpdateTime string `json:"update_time"`
}

func GetById(table string, id int) (params orm.Params, err error) {
	return GetByCondition(table, orm.NewCondition().And("id", id))
}

func GetByCondition(table string, condition *orm.Condition) (p orm.Params, err error) {
	var params []orm.Params
	_, err = orm.NewOrm().QueryTable(getTable(table)).OrderBy("-Id").SetCond(condition).Values(&params)
	if err != nil {
		return
	}
	return params[0], err
}

//从单表中根据条件获取数据列表
//@param            table           需要查询的表
//@param            p               页码
//@param            listRows        每页显示记录数
//@param            condition       查询条件
//@param            orderBy         排序
//@return           params          数据列表
//@return           rows            返回总数
//@return           err             错误
func GetList(table string, p, listRows int, condition *orm.Condition, orderBy ...string) (params []orm.Params, rows int64, err error) {
	_, err = orm.NewOrm().QueryTable(getTable(table)).SetCond(condition).Limit(listRows).Offset((p - 1) * listRows).OrderBy(orderBy...).Values(&params)
	if err == nil {
		params = MapToJson(params)
	}
	rows, _ = GetCount(table, condition)
	return params, rows, err
}

func GetCount(table string, condition *orm.Condition) (rows int64, err error) {
	rows, err = orm.NewOrm().QueryTable(getTable(table)).SetCond(condition).Count()
	return rows, err
}

//从单表中根据条件获取数据列表
//@param            table           需要查询的表
//@param            condition       查询条件
//@param            orderBy         排序
//@return           params          数据列表
//@return           rows            返回的记录数
//@return           err             错误
func GetAllData(table string, condition *orm.Condition, orderBy ...string) (params []orm.Params, rows int64, err error) {
	rows, err = orm.NewOrm().QueryTable(getTable(table)).SetCond(condition).OrderBy(orderBy...).Values(&params)
	if err == nil {
		params = MapToJson(params)
	}
	return params, rows, err
}

//创建新数据
//@models 添加数据 struct
//@return rows 添加行数
//@return err
func Create(models interface{}) (rows int64, err error) {
	models = setTime(models, 1)
	return orm.NewOrm().Insert(models)
}

//更新数据
//@models 更新数据 struct
//@return rows 更新行数
//@return err
func UpdateByCondition(models interface{}) (rows int64, err error) {
	models = setTime(models, 2)
	fields := getFields(models)
	return orm.NewOrm().Update(models, fields...)
}

//根据条件删除
//@table 表名
//@params condition 条件
//@return rows
//@return error
func DeleteByCondition(table string, condition *orm.Condition) (int64, error) {
	return orm.NewOrm().QueryTable(getTable(table)).SetCond(condition).Delete()
}

//根据id删除
//@table 表名
//@params condition 条件
//@return rows
//@return error
func DeleteById(table string, id int) (int64, error) {
	return orm.NewOrm().QueryTable(getTable(table)).SetCond(orm.NewCondition().And("id", id)).Delete()
}

func getFields(models interface{}) []string {
	var fields = make([]string, 0)
	t := reflect.TypeOf(models).Elem()
	v := reflect.ValueOf(models).Elem()
	for i := 0; i < v.NumField(); i++ {
		switch v.Field(i).Kind() {
		case reflect.Int, reflect.Int64:
			if !v.Field(i).IsZero() {
				fields = append(fields, getColumnName(t.Field(i)))
			}
		case reflect.String:
			if v.Field(i).String() != "" {
				fields = append(fields, getColumnName(t.Field(i)))
			}
		case reflect.Struct:
			createTime, _ := t.FieldByName("CreateTime")
			updateTime, _ := t.FieldByName("UpdateTime")
			cIndex := createTime.Index
			uIndex := updateTime.Index
			for l := 0; l < v.Field(i).NumField(); l++ {
				value := v.Field(i).Field(l)
				if value.String() != "" {
					if i == cIndex[0] && l == cIndex[1] {
						fields = append(fields, getColumnName(createTime))
					}
					if i == uIndex[0] && l == uIndex[1] {
						fields = append(fields, getColumnName(updateTime))
					}
				}
			}
		}
	}
	return fields
}

//获取字段名
//@params
//return 字段名称
func getColumnName(v reflect.StructField) string {
	var column = v.Name
	if v.Tag.Get("json") != "" {
		column = v.Tag.Get("json")
	}
	return column
}

//设置时间
//@params models
//@params operateType 1 添加 2修改
//@return models
func setTime(models interface{}, operateType int) interface{} {
	t := time.Now().Format("2006-01-02 15:04:05")
	var c, u string
	u = t
	if operateType == 1 {
		c = t
	}
	v := reflect.ValueOf(models).Elem()
	v.FieldByName("BaseModels").Set(reflect.ValueOf(BaseModels{c, u}))
	return models
}

//获取表前缀名称
//@param  table 表名
//@return table 带前缀的表名
func getTable(table string) string {
	//	prefix := beego.AppConfig.DefaultString("db::prefix", "hc_")
	//if !strings.HasPrefix(table, prefix) {
	//	table = prefix + table
	//}
	return table
}

//查询是否存在
//@param table 表名
//@param condition 条件
//@return bool
func Exist(table string, condition *orm.Condition) bool {
	o := orm.NewOrm().QueryTable(getTable(table))
	//condition = condition.And("deleted", 0)
	return o.SetCond(condition).Exist()
}
